#ifndef _DEBOUNCE_C
#define _DEBOUNCE_C

char countA, countB, debounced;

char debounce( void )
/*
{
; Inputs:
;   csa - The current sample
; Outputs
;   cva - The current value (filtered version of csa)
;   W   - Bits that have just been filtered.
;
; RAM used
;   count_A,
;   count_B - State variables for the 8 2-bit counters
;
de_bounce:
    ;Increment the vertical counter
        MOVF    count_B,W
        XORWF   count_A,F
        COMF    count_B,F

    ;See if any changes occurred
        MOVF    csa,W
        XORWF   cva,W

    ;Reset the counter if no change has occurred
        ANDWF   count_B,F
        ANDWF   count_A,F

    ;If there is a pending change and the count has
    ;rolled over to 0, then the change has been filtered
        XORLW   0xff            ;Invert the changes
        IORWF   count_A,W       ;If count is 0, both A and B
        IORWF   count_B,W       ;bits are 0

    ;Any bit in W that is clear at this point means that the input
    ;has changed and the count has rolled over.

        XORLW   0xff

    ;Now W holds the state of inputs that have just been filtered
    ;to a new state. Update the changes:

        XORWF   cva,F

    ;leave with W holding the state of all filtered bits that have 
    ;change state

        RETURN
*/
{
   char delta, changes;

   delta = GPIO ^ debounced;

   countA ^= countB;
   countB = ~countB;

   countA &= delta;
   countB &= delta;

   changes = ~( ~delta | countA | countB );
   debounced ^= changes;

   return( debounced );
}

#endif